#pragma once
#include "RdcBuffer.h"

#include <boost/tr1/memory.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>

namespace rdc_transport
{
    struct IVirtChannel;

    class WriteImplStrategy
    {
    public:
        WriteImplStrategy();

    public:
        void Write(Buffer* buffer);

    public:
        void WriteComplete(LPVOID, UINT32, UINT32, UINT32);
        void WriteCancelled(LPVOID, UINT32, UINT32, UINT32);
        void SetInternalWriter(IVirtChannel* write);

    private:
        boost::mutex m_writeLock;
        boost::condition_variable m_writeComplete;
        bool m_cancelled;
        
        std::tr1::shared_ptr<IVirtChannel> m_write;
    };

    class WriteWithProtocol : public WriteImplStrategy
    {
    public:
        void Write(Buffer* buffer)
        {
            WriteImplStrategy::Write(buffer);
        }
    };

    class WriteNoProtocol : public WriteImplStrategy
    {
    public:
        void Write(Buffer* buffer)
        {
            const size_t size = buffer->size();

            //to avoid big endian:
            Buffer bufferSize((char*)&size, (char*)&size + sizeof size);
            WriteImplStrategy::Write(&bufferSize);
            WriteImplStrategy::Write(buffer);
        }
    };
}

